﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using Microsoft.Forums.MicrosoftForumsProvider;
using Microsoft.Forums.SyncService;
using Microsoft.Forums.OfflineStore;
using System.Globalization;

namespace Microsoft.Forums.ForumsClient
{
    /// <summary>
    /// Interaction logic for SubscribeToForums.xaml
    /// </summary>
    public partial class SubscribeToForums : Window
    {
        private SynchronizationController syncController;
        private string connectionString;

        /// <summary>
        ///  Subscription Dialog 
        /// </summary>
        /// <param name="controller">Synchronization controller that is used to communicate to the Forums Web Services</param>
        /// <param name="databaseConnectionString">name of database file</param>
        public SubscribeToForums(SynchronizationController controller, string databaseConnectionString)
        {
            InitializeComponent();

            if (controller == null)
                throw new ArgumentNullException("SynchronizationController cannot be null");

            if (String.IsNullOrEmpty(databaseConnectionString) == true)
                throw new ArgumentNullException("databaseConnectionString cannot be null or String.Empty");

            connectionString = databaseConnectionString;
            syncController = controller;
            this.Cursor = Cursors.Wait;
        }

        protected override void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);
            Locale defaultLocale = null;

            // Load available locales collection
            Locale locale;
            ObservableCollection<Locale> localeCollection = ((LocaleCollection)this.Resources["availableLocales"]).AvailableLocalesCollection;
            foreach (KeyValuePair<int, string> pair in syncController.SupportedLocales)
            {
                locale = new Locale();
                locale.LocaleName = pair.Value;
                locale.LocaleIndex = pair.Key;
                localeCollection.Add(locale);
                if (pair.Value == Properties.Resources.DefaultLocale)
                {
                    defaultLocale = locale;
                }
            }

            ObservableCollection<Brand> brandCollection = ((BrandsCollection)this.Resources["forumsBrands"]).BrandCollection;
            // Load available Brands collection
            foreach (string brandName in syncController.SupportedBrands)
            {
                Brand brand = new Brand();
                brand.BrandName = brandName;
                brandCollection.Add(brand);
            }

            // Enable the controls
            this.LocaleComboBox.IsEnabled = true;
            this.BrandComboBox.IsEnabled = true;
            this.DaysComboBox.IsEnabled = true;
            this.FinishButton.IsEnabled = true;
            this.CancelButton.IsEnabled = true;
            this.FilterTextBox.IsEnabled = true;

            // Set en-US as default locale
            this.LocaleComboBox.SelectedItem = defaultLocale;

            // Set cursor to be the usual arrow
            this.Cursor = Cursors.Arrow;
        }

        private void BrandOrLocaleComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            RefreshAvailableForums();
        }

        private void AddForumToPreviewArea(object sender, RoutedEventArgs e)
        {
            Forum selectedForum = (Forum)this.AvailableForumsListBox.SelectedItem;
            if (selectedForum != null)
            {
                BrandForumsCollection.AvailableForumsCollection.Remove(selectedForum);
                PreviewForumsCollection.Instance.Add(selectedForum);
                this.AvailableForumsListBox.SelectedIndex = -1;
            }
        }

        private void RemoveForumFromPreviewArea(object sender, RoutedEventArgs e)
        {
            Forum selectedForum = (Forum)this.PreviewForumsListBox.SelectedItem;
            if (selectedForum != null)
            {
                PreviewForumsCollection.Instance.Remove(selectedForum);
                this.PreviewForumsListBox.SelectedIndex = -1; 

                // This will cause the Forum to reappear in the available
                // forums list if it's the current brand selection, not in the preview area and not subscribed)
                if (selectedForum.Locale == (string)this.ForumsLocaleLabel.Content &&
                    selectedForum.Brand == (string)this.AvailableBrandForumsLabel.Content)
                {
                    BrandForumsCollection.AddToBrandForumsCollection(selectedForum, connectionString);
                }
            }
        }


        private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            string filterText = FilterTextBox.Text.ToLower(CultureInfo.CurrentCulture);

            AvailableForumsListBox.Items.Filter =
                delegate(object o)
                {
                    if (o == null) return false;
                    Forum forum = (Forum)o;
                    return
                        String.IsNullOrEmpty(filterText) ||
                        forum.Name.ToLower(CultureInfo.CurrentCulture).Contains(filterText) ||
                        forum.DisplayName.ToLower(CultureInfo.CurrentCulture).Contains(filterText) ||
                        forum.Description.ToLower(CultureInfo.CurrentCulture).Contains(filterText);

                };
        }

        private void RefreshAvailableForums()
        {
            // If brand and locale have both been selelcted, refresh available forums display.
            if (this.LocaleComboBox.SelectedIndex >= 0 && this.BrandComboBox.SelectedIndex >= 0)
            {
                // Set the labels for the separator bar that reads something like
                // Available Expression (Locale en-US)to which you are not subscribed
                this.AvailableLabel.Content = Properties.Resources.AvailableLabelContent;
                this.AvailableBrandForumsLabel.Content = this.BrandComboBox.SelectedItem.ToString();
                this.ForumsLocaleLabel.Content = Properties.Resources.ForumsLocaleLabelContent;
                this.SelectedLocaleLabel.Content = this.LocaleComboBox.SelectedItem.ToString();
                this.NotSubscribedLabel.Content = Properties.Resources.NotSubscribedLabelContent;
                BrandForumsCollection.AvailableForumsCollection.Clear();

                 // Make API call to get forums 
                foreach (Forum msdnForum in syncController.GetAvailableForums(this.BrandComboBox.SelectedItem.ToString(), ((Locale)this.LocaleComboBox.SelectedItem).LocaleIndex))
                {
                    msdnForum.Brand = (string) this.AvailableBrandForumsLabel.Content;
                    msdnForum.Locale = (string) this.ForumsLocaleLabel.Content;
                    BrandForumsCollection.AddToBrandForumsCollection(msdnForum, connectionString);
                }
                if (BrandForumsCollection.AvailableForumsCollection.Count == 0)
                {
                    this.AvailableLabel.Content = Properties.Resources.AlternateAvailableLabelContent;
                }
            }
        }

        private void FinishButton_Click(object sender, RoutedEventArgs e)
        {
            string selectedItem = ((ComboBoxItem)this.DaysComboBox.SelectedItem).Content.ToString();
            var forumProperties = new ForumPropertySet() { InitialSyncAge = null, SyncFrequency = 10 };


            // TODO in M2 add logic to get SyncFrequency
            // If user has set values with Synch Settings Dialog, add all of them
            // to the properties set.
            // Else just add the default SyncFrequency from the DB.
            forumProperties = new ForumPropertySet() { InitialSyncAge = System.Int32.Parse(selectedItem), SyncFrequency = 10 };

            // Subscrribe to each forum in the preview area
            foreach (Forum forum in PreviewForumsCollection.Instance)
            {
                syncController.SubscribeToForum(forum, forumProperties);
            }

            // Remove the objects from the static collection so they can be GC'ed
            PreviewForumsCollection.Instance.Clear();
            BrandForumsCollection.AvailableForumsCollection.Clear();
            DialogResult = true;
            this.Close();
        }

        private void AvailableForumsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.AddButton.IsEnabled = (this.AvailableForumsListBox.SelectedIndex >= 0)?true:false;
        }

        private void PreviewForumsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.RemoveButton.IsEnabled = (this.PreviewForumsListBox.SelectedIndex >= 0) ? true : false;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
        }
    }
}
